﻿package com.mod.engine {
	
    import com.calefk.core.List;
	import com.calefk.core.Task;
    import com.calefk.core.TemporaryManager;
    import com.calefk.modules.sysfx.SystemFx;
    import com.calefk.util.Logger;
	import com.mod.data.dtLevel;
	import com.mod.enemies.EnemyManager;
	import com.mod.Global;
	import com.mod.ModProject;
    import com.mod.page.GamePage;
	import com.mod.PMGame;
	import com.mod.reanimator.BaseVillager;
	import com.mod.reanimator.HeartSkin;
	import com.mod.reanimator.Player;
	import com.mod.reanimator.villager;
	import com.mod.reanimator.World;
    
    import flash.display.MovieClip;
    import flash.events.KeyboardEvent;
    import flash.ui.Keyboard;
    /**
     * Esta clase es una desacoplación de GamePage , crear aquí todos los objetos , logica de colisiones  (gameplay)
     */
	public class Engine {
		
		private var mGamePage:GamePage;
		private var mCanvas:MovieClip;
        private var mPlayer:Player;
		public var toClean:Boolean;
        private var mWorld:World;
		private var hearth:MovieClip;
		public function get player():Player { return mPlayer;  }
		public function get world():World  { return mWorld;   }
		public function get enemyManager():EnemyManager  { return mEnemyManager;   }
		public function get heartSkin():HeartSkin  { return mHeartSkin;   }
		
		
		public static const ST_WIN:int = 0;
		public static const ST_UPDATE:int = 1;
		public static const ST_OVER:int = 2;
		private var mState:int;
		
		private var mEnemyManager:EnemyManager;
		private var mHeartSkin:HeartSkin;
		
		private var mTasks:List = new List();
		
		public function Engine(gamePage:GamePage , canvas:MovieClip) {
			mCanvas = canvas;
			mGamePage = gamePage;
            
            // Initialize System Fx
            SystemFx.initialize(1000 / 30, mCanvas);
            

			
			mEnemyManager = new EnemyManager(canvas);
			
			//Create Player
			var nameWorld:String;
			switch (Global.currentLevel) {
				case 0:
					nameWorld = "level1";
					break;
				case 1:
					nameWorld = "level2";
					break;
				case 2:
					nameWorld = "level3";
					break;
			}
			mWorld = new World(canvas, nameWorld, 0, 0, null, mEnemyManager);
			
			mHeartSkin = new HeartSkin(mWorld.clip.heart_skin);
			mHeartSkin.onFinishDie = onFinishSkin;
			
			/* mEnemyManager.init se llama aqui debido a que necesito la instancia de heart skin
			 * */
			mEnemyManager.init(mHeartSkin);
			
			mPlayer = new Player(canvas, "Player", 100, 100);
			mWorld.player = mPlayer;
			mPlayer.hearthWorld = mWorld.hearth;
			mPlayer.assigLimitsHearth();
			canvas.stage.focus = mCanvas.stage;
			
			
			Logger.echo("::: Create Engine :::");
			
			mState = ST_UPDATE;
			mTasks.add(new Task(onFirstCheck , 2000));
		}
		
		private function onFirstCheck():void {
			onCheckOverGame();
		}
		
		private function onFinishSkin():void 
		{
			mState = ST_OVER;
            ModProject.getPM().onTransition(600, 300 , PMGame.PAGE_OVER , null , null , 0xffffff , Global.SW , Global.SH); 

		}		
        
		public function update(dt:int):void {
            // update system
            SystemFx.instance.update(dt);
			
			if (mTasks) {
				mTasks.update(dt);
			}
			
			switch (mState) {
				case ST_UPDATE:
					if (mPlayer)
					{
						mPlayer.update(dt);
					}
					if (mWorld)
					{
						mWorld.update(dt);
					}
					
					if (mEnemyManager) {
						mEnemyManager.update(dt);
					}					
					break;
				case ST_WIN:
				case ST_OVER:
					break;
			}
			

		}
		
		public function onStartWinLevel():void {
			mState = ST_WIN;
			if (Global.currentLevel + 1 == (Global.dataGame.levels.length)) {
				// mostrar pagina final
				Global.project.pageManager.onTransition(300 , 300 , PMGame.PAGE_WIN , null , null , 0x000000 , Global.SW , Global.SH);
				trace("Win Game");
			} else {
				// recargar la pagina de juegos
				Global.currentLevel++;
				Global.project.pageManager.onTransition(300 , 300 , PMGame.PAGE_GAME , null , null , 0x000000 , Global.SW , Global.SH);
			}
		}
		
		private function onCheckOverGame():void {
			var deaths:int = 0;
			var alives:int = 0;
			
			for (var k:int = 0; k < mWorld.arrayVillagers.length; k++) {
				var v:* = mWorld.arrayVillagers[k];
				if (v is villager) {
					// si está muerto
					if (BaseVillager(v).currentState == BaseVillager.DEATH) {
						deaths++;
					}
					else if (BaseVillager(v).currentState == BaseVillager.MOVING
						|| BaseVillager(v).currentState == BaseVillager.REVIVING) {
						alives++;
					}
				}
			}
			// data level
			var datalevel:dtLevel = Global.dataGame.levels[Global.currentLevel];
			// deaths master games
			var mount_current_to_win:int = datalevel.numEnterBaseWin - mHeartSkin.counterEnterBase;
			
			
			// si hay nemos 
			if ( (mount_current_to_win > 0 ) && 
					(deaths < mount_current_to_win && alives == 0) ) {
				// debes perder
				trace("Over Game Check Deaths" );
				onOverGame();
			} else {
				mTasks.add(new Task(onCheckOverGame , 200));
			}
		}
		
		private function onGotoOver():void {
            ModProject.getPM().onTransition(600, 300 , PMGame.PAGE_OVER , null , null , 0x000000 , Global.SW , Global.SH); 			
		}
		
		public function onOverGame():void {
			mState = ST_OVER;
			mTasks.add(new Task(onGotoOver , 500));
		}
        
        public function onKeyDown(e:KeyboardEvent):void {
			mPlayer.onKeyDown(e);
        }
		
		public function onKeyUp(e:KeyboardEvent):void {
			mPlayer.onKeyUp(e);
		}
		
		public function endGame():void {
			toClean = true;
        }
		
		public function clean():void { 
            SystemFx.cleanSystem();
			
			if (mWorld) {
				mWorld.clean();
				mWorld = null;
			}
			mGamePage = null;
			mCanvas = null;
		}
	}
}